/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package vista.compras;

import com.itextpdf.text.DocumentException;
import java.awt.Color;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JViewport;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
import modelo.*;
import org.hibernate.Transaction;
import util.HibernateUtil;
import util.SwingPanel;
import util.TablaUtil;
import util.Tupla;
import vista.comer.pantallaListadoProveedores;
import vista.interfaces.ICallBackGen;
import vista.interfaces.ICallBackObject;
import vista.reportes.ReportDesigner;
import vista.reportes.sources.EmitirOrdenDeCompra;

/**
 *
 * @author Administrador
 */
public class GenerarNuevaOrdenDeCompra extends javax.swing.JInternalFrame implements ICallBackGen, ICallBackObject {

    public static final String CALLBACK_SELECCION_PROVEEDOR   = "SeleccionDeProveedor";
    public static final String CALLBACK_SELECCION_ITEMDETALLE = "SeleccionItemDetalle";
    
    private Proveedor proveedorSeleccionado;
    private OrdenDeCompra ordenDeCompraCargada;
    private List<DetalleOrdenDeCompra> listadoDetalleOrdenDeCompra;
    
    /**
     * Permite crear desde cero una orden de compra (por ejemplo si se llama desde el menu principal)
     */
    public GenerarNuevaOrdenDeCompra() {
        listadoDetalleOrdenDeCompra = new ArrayList<DetalleOrdenDeCompra>();
        initComponents();
        initComboFormaDePago();
        initComboFormaDeEntrega();
        initAnchoColumnasTablaDetalles();
        txtEstado.setText(OrdenDeCompra.ESTADO_EN_CREACION);
        txtFecha.setDate(new Date());
    }

    /**
     * (número orden compra): Carga los datos, y si el estado lo permite, el usuario puede modificarlo.
     * @param idOrdenDeCompra 
     */
    public GenerarNuevaOrdenDeCompra(int idOrdenDeCompra) {
        listadoDetalleOrdenDeCompra = new ArrayList<DetalleOrdenDeCompra>();
        initComponents();
        initComboFormaDePago();    
        initComboFormaDeEntrega();
        initAnchoColumnasTablaDetalles();
        initDatos(idOrdenDeCompra);
        initEstado();
    }
    
    /**
     * (obra,proveedor,List): Abre en modo de creacion, pero ya tiene seleccionado 
     * el proveedor y llenado el detalle con lo que se paso por parametro, esto 
     * permite asociar una orden de compra a una obra especifica, pero solo con 
     * el fin de trazabilidad. ( Esto es lo que se va a usar para generar ordenes 
     * desde la ejecucion de una Obra)
     */
    public GenerarNuevaOrdenDeCompra(PedidoObra obra, Proveedor p, List<DetalleOrdenDeCompra> listaItemsOrden) {
        listadoDetalleOrdenDeCompra = new ArrayList<DetalleOrdenDeCompra>();
        initComponents();
        initComboFormaDePago();  
        initComboFormaDeEntrega();
        initAnchoColumnasTablaDetalles();
        initDatos(obra, p, listaItemsOrden);
        txtEstado.setText(OrdenDeCompra.ESTADO_EN_CREACION);
        initEstado();
        txtFecha.setDate(new Date());
    }    

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel1 = new javax.swing.JPanel();
        txtNroOrdenDeCompra = new javax.swing.JTextField();
        jPanel2 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        cmbFormaDePago = new javax.swing.JComboBox();
        jLabel3 = new javax.swing.JLabel();
        cmbFormaDeEntrega = new javax.swing.JComboBox();
        jLabel4 = new javax.swing.JLabel();
        txtProveedor = new javax.swing.JTextField();
        btnSeleccionarProveedor = new javax.swing.JButton();
        txtFecha = new com.toedter.calendar.JDateChooser();
        jLabel5 = new javax.swing.JLabel();
        txtEstado = new javax.swing.JTextField();
        jPanel3 = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        tblDetalle = new javax.swing.JTable();
        btnAgregar = new javax.swing.JButton();
        btnQuitar = new javax.swing.JButton();
        txtTotal = new javax.swing.JTextField();
        jLabel6 = new javax.swing.JLabel();
        btnGuardar = new javax.swing.JButton();
        btnRegistrarRecepcion = new javax.swing.JButton();
        btnEmitir = new javax.swing.JButton();
        btnCancelar = new javax.swing.JButton();
        btnAnular = new javax.swing.JButton();

        setClosable(true);
        setIconifiable(true);
        setMaximizable(true);
        setResizable(true);
        setTitle("Generar Nueva Orden de Compra");

        jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Número de la Orden"));

        txtNroOrdenDeCompra.setBackground(new java.awt.Color(204, 204, 204));
        txtNroOrdenDeCompra.setEditable(false);
        txtNroOrdenDeCompra.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
        txtNroOrdenDeCompra.setHorizontalAlignment(javax.swing.JTextField.RIGHT);

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(txtNroOrdenDeCompra)
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(txtNroOrdenDeCompra, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
        );

        jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("Datos Generales"));

        jLabel1.setText("Fecha:");

        jLabel2.setText("Forma de Pago:");

        jLabel3.setText("Forma de Entrega:");

        jLabel4.setText("Proveedor:");

        txtProveedor.setBackground(new java.awt.Color(204, 204, 204));
        txtProveedor.setEditable(false);

        btnSeleccionarProveedor.setText("...");
        btnSeleccionarProveedor.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSeleccionarProveedorActionPerformed(evt);
            }
        });

        jLabel5.setText("Estado:");

        txtEstado.setBackground(new java.awt.Color(204, 204, 204));
        txtEstado.setEditable(false);

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jLabel2, javax.swing.GroupLayout.DEFAULT_SIZE, 97, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(cmbFormaDePago, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(txtFecha, javax.swing.GroupLayout.DEFAULT_SIZE, 123, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(jLabel3, javax.swing.GroupLayout.DEFAULT_SIZE, 96, Short.MAX_VALUE)
                    .addComponent(jLabel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jLabel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(cmbFormaDeEntrega, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addComponent(txtProveedor)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btnSeleccionarProveedor))
                    .addComponent(txtEstado)))
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(jLabel4)
                    .addComponent(txtProveedor, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(btnSeleccionarProveedor)
                    .addComponent(txtFecha, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 14, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(cmbFormaDePago, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel3)
                    .addComponent(cmbFormaDeEntrega, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel5)
                    .addComponent(txtEstado, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
        );

        jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder("Detalle de la Orden de Compra"));

        tblDetalle.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {
                "Nombre y Descripción", "Cantidad", "Precio", "SubTotal"
            }
        ) {
            boolean[] canEdit = new boolean [] {
                false, false, false, false
            };

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        jScrollPane1.setViewportView(tblDetalle);

        btnAgregar.setIcon(new javax.swing.ImageIcon(getClass().getResource("/res/iconos/var/16x16/add.png"))); // NOI18N
        btnAgregar.setText("Agregar");
        btnAgregar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnAgregarActionPerformed(evt);
            }
        });

        btnQuitar.setIcon(new javax.swing.ImageIcon(getClass().getResource("/res/iconos/var/16x16/delete.png"))); // NOI18N
        btnQuitar.setText("Quitar");
        btnQuitar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnQuitarActionPerformed(evt);
            }
        });

        txtTotal.setBackground(new java.awt.Color(204, 204, 204));
        txtTotal.setEditable(false);
        txtTotal.setHorizontalAlignment(javax.swing.JTextField.RIGHT);
        txtTotal.setText("$ -");

        jLabel6.setFont(new java.awt.Font("Tahoma", 1, 11)); // NOI18N
        jLabel6.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
        jLabel6.setText("Total:");

        javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
        jPanel3.setLayout(jPanel3Layout);
        jPanel3Layout.setHorizontalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 614, Short.MAX_VALUE)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addComponent(btnAgregar)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(btnQuitar)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, 62, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(txtTotal, javax.swing.GroupLayout.PREFERRED_SIZE, 129, javax.swing.GroupLayout.PREFERRED_SIZE))
        );
        jPanel3Layout.setVerticalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 244, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(btnAgregar)
                    .addComponent(btnQuitar)
                    .addComponent(txtTotal, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel6)))
        );

        btnGuardar.setIcon(new javax.swing.ImageIcon(getClass().getResource("/res/iconos/var/16x16/save_upload.png"))); // NOI18N
        btnGuardar.setText("Guardar");
        btnGuardar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnGuardarActionPerformed(evt);
            }
        });

        btnRegistrarRecepcion.setIcon(new javax.swing.ImageIcon(getClass().getResource("/res/iconos/var/16x16/new_page.png"))); // NOI18N
        btnRegistrarRecepcion.setText("Registrar Recepción");
        btnRegistrarRecepcion.setEnabled(false);
        btnRegistrarRecepcion.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnRegistrarRecepcionActionPerformed(evt);
            }
        });

        btnEmitir.setIcon(new javax.swing.ImageIcon(getClass().getResource("/res/iconos/var/16x16/print.png"))); // NOI18N
        btnEmitir.setText("Emitir Orden de Compra");
        btnEmitir.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnEmitirActionPerformed(evt);
            }
        });

        btnCancelar.setIcon(new javax.swing.ImageIcon(getClass().getResource("/res/iconos/var/16x16/block.png"))); // NOI18N
        btnCancelar.setText("Cerrar");
        btnCancelar.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnCancelarActionPerformed(evt);
            }
        });

        btnAnular.setIcon(new javax.swing.ImageIcon(getClass().getResource("/res/iconos/var/16x16/delete.png"))); // NOI18N
        btnAnular.setText("Anular");
        btnAnular.setEnabled(false);
        btnAnular.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnAnularActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(btnGuardar)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btnEmitir)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btnRegistrarRecepcion)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(btnAnular)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(btnCancelar)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(btnGuardar)
                    .addComponent(btnRegistrarRecepcion)
                    .addComponent(btnEmitir)
                    .addComponent(btnCancelar)
                    .addComponent(btnAnular))
                .addContainerGap())
        );

        jPanel3.getAccessibleContext().setAccessibleName("Detalle de la Orden de Compra");

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void btnCancelarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnCancelarActionPerformed
        this.dispose();
    }//GEN-LAST:event_btnCancelarActionPerformed

    private void btnSeleccionarProveedorActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSeleccionarProveedorActionPerformed
        pantallaListadoProveedores win = new pantallaListadoProveedores();
        win.setSeleccionarEnabled(this,GenerarNuevaOrdenDeCompra.CALLBACK_SELECCION_PROVEEDOR);
        SwingPanel.getInstance().addWindow(win);
        win.setVisible(true);
    }//GEN-LAST:event_btnSeleccionarProveedorActionPerformed

    private void btnAgregarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAgregarActionPerformed
        
        boolean validado = true;
        StringBuilder msg = new StringBuilder("<HTML>Para poder agegar un item seleccione el <b>Proveedor</b> al que se le realizará la compra");
        
        // Proveedor
        if(txtProveedor.getText().isEmpty() || this.proveedorSeleccionado==null)
        {
            validado = false;
        }
        
        if(validado)
        {
            GenerarNuevaOrdenDeCompraAgregarRecurso win = new GenerarNuevaOrdenDeCompraAgregarRecurso(this,this.proveedorSeleccionado);
            SwingPanel.getInstance().addWindow(win);
            win.setVisible(true);
        }
        else
        {
            mostrarMensaje(JOptionPane.ERROR_MESSAGE,"Error de Validación!",msg.toString());
        }
    }//GEN-LAST:event_btnAgregarActionPerformed

    private void btnQuitarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnQuitarActionPerformed
        if(tblDetalle.getSelectedRow()>=0){
            
            // Esta seguro?
            int seleccion = JOptionPane.showOptionDialog(
                this, // Componente padre
                "¿Está seguro que desea elmininar esta fila de la Orden de Compra?", //Mensaje
                "Seleccione una opción", // Titulo
                JOptionPane.YES_NO_CANCEL_OPTION,
                JOptionPane.QUESTION_MESSAGE,
                null,    // null para icono por defecto.
                new Object[] { "Si", "No"},    // null para YES, NO y CANCEL
                "Si");
                if (seleccion != -1)
                {
                    if((seleccion + 1)==1)
                    {
                        // PRESIONO SI
                        Tupla tp = (Tupla)tblDetalle.getModel().getValueAt(tblDetalle.getSelectedRow(),0);
                        if(tp!=null)
                        {
                            // Remuevo de los datos de la clase
                            for (int i = 0; i < listadoDetalleOrdenDeCompra.size(); i++) {
                                DetalleOrdenDeCompra doc = listadoDetalleOrdenDeCompra.get(i);
                                
                                if(doc.getId()!=0)
                                {
                                    if(ordenDeCompraCargada!=null)
                                    {
                                        for (int j = 0; j < this.ordenDeCompraCargada.getDetalle().size(); j++) {
                                            DetalleOrdenDeCompra detalleOrdenDeCompra =  this.ordenDeCompraCargada.getDetalle().get(j);
                                            if(detalleOrdenDeCompra.hashCode()==tp.getId())
                                            {
                                                this.ordenDeCompraCargada.getDetalle().remove(j);
                                                break;
                                            }
                                        }
                                    }
                                }
                                
                                if(doc.hashCode()==tp.getId())
                                {
                                    listadoDetalleOrdenDeCompra.remove(i);
                                    break;
                                }
                            }
                            // Remuevo del Modelo
                            DefaultTableModel model = (DefaultTableModel) tblDetalle.getModel();
                            model.removeRow(tblDetalle.getSelectedRow());
                            actualizarTotalCompra();
                        }                        
                    }
                }
        }
        else
        {
            JOptionPane.showMessageDialog(this, "Debe seleccionar una fila de la Orden de Compra","Advertencia!",JOptionPane.WARNING_MESSAGE);
        }
    }//GEN-LAST:event_btnQuitarActionPerformed

    private void btnRegistrarRecepcionActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRegistrarRecepcionActionPerformed
        // Si ya tengo el numero !!
        if(!txtNroOrdenDeCompra.getText().isEmpty())
        {
            // Y ya está emitida
            if(txtEstado.getText().equals(OrdenDeCompra.ESTADO_EMITIDA))
            {
                int id = Integer.parseInt(txtNroOrdenDeCompra.getText());
                mostrarRecepcion(id);
                this.dispose();
            }
            else
            {
                mostrarMensaje(JOptionPane.ERROR_MESSAGE,"Error!","Emita la orden de Compra antes de Registrar su recepción");
            }
        }
        else
        {
            mostrarMensaje(JOptionPane.ERROR_MESSAGE,"Error!","Guarde la Orden de compra antes de Registrar su recepción");
        }
    }//GEN-LAST:event_btnRegistrarRecepcionActionPerformed

    private void btnGuardarActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnGuardarActionPerformed
        
        int n = JOptionPane.showConfirmDialog(
                new JFrame(),
                "¿Está seguro que desea guardar la Orden de Compra?",
                "Atencion!",
                JOptionPane.YES_NO_OPTION);
        
        if(n==JOptionPane.YES_OPTION)
        {
            if(validar())
            {
                if(ordenDeCompraCargada==null)
                {
                    crearYguardar();
                }
                else
                {
                    actualizarYGuardar();
                }
                initEstado();
            }
        }

    }//GEN-LAST:event_btnGuardarActionPerformed

    private void btnEmitirActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnEmitirActionPerformed

        // Si ya esta emitida, la muestro de una
        if(this.ordenDeCompraCargada!=null && this.ordenDeCompraCargada.getId()!=0)
        {
            // Si ya esta emitida, muestro de una
            if(OrdenDeCompra.ESTADO_EMITIDA.equals(this.ordenDeCompraCargada.getEstado()) || OrdenDeCompra.ESTADO_ANULADA.equals(this.ordenDeCompraCargada.getEstado()))
            {
                emitirOrdenDeCompra();
                return;
            }
        }
        String msg = "<HTML>Esta por emitir la orden de compra<br>Y una vez que está emitida NO podrá modificarse<br>¿Desea guardar los cambios y continar?";
        
        int seleccion = JOptionPane.showOptionDialog(
                        this, // Componente padre
                        msg, //Mensaje
                        "Seleccione una opción", // Titulo
                        JOptionPane.YES_NO_CANCEL_OPTION,
                        JOptionPane.QUESTION_MESSAGE,
                        null,    // null para icono por defecto.
                        new Object[] { "Guardar y Continuar", "Cancelar"},    // null para YES, NO y CANCEL
                        "Guardar y Continuar");
        
        if (seleccion != -1)
        {
            if((seleccion + 1)==1)
            {     
                if(validar())
                {
                    boolean exito = false;
                    if(ordenDeCompraCargada==null)
                    {
                        exito = crearYguardar();
                    }
                    else
                    {
                        exito = actualizarYGuardar();
                    }
                    if(exito)
                    {
                        // Cambio el estado de la ODC a EMITIDA !
                        if(cambiarEstadoAEmitida())
                        {
                            emitirOrdenDeCompra();
                        }
                    }
                }
            }
        }
        
    }//GEN-LAST:event_btnEmitirActionPerformed

    private void btnAnularActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnAnularActionPerformed
        // Si ya tengo el numero !!
        if(!txtNroOrdenDeCompra.getText().isEmpty())
        {
            // Y ya esta emitida
            if(txtEstado.getText().equals(OrdenDeCompra.ESTADO_PENDIENTE) || 
               txtEstado.getText().equals(OrdenDeCompra.ESTADO_EN_CREACION))
            {
               int seleccion = JOptionPane.showOptionDialog(
                                this, // Componente padre
                                "¿Desea anular la orden de compra?\nNo podrá modificarla en un futuro.", //Mensaje
                                "Seleccione una opción", // Titulo
                                JOptionPane.YES_NO_CANCEL_OPTION,
                                JOptionPane.QUESTION_MESSAGE,
                                null,    // null para icono por defecto.
                                new Object[] { "Si", "No"},    // null para YES, NO y CANCEL
                                "Si"); 
                if (seleccion != -1)
                {
                    if((seleccion + 1)==1)
                    {
                        // PRESIONO SI
                        int id = Integer.parseInt(txtNroOrdenDeCompra.getText());
                        anularOrdenDeCompra(id);
                    }
                }               
            }
            else
            {
                mostrarMensaje(JOptionPane.ERROR_MESSAGE,"Error!","Esta orden de compra no puede anularse");
            }
        }
        else
        {
            mostrarMensaje(JOptionPane.ERROR_MESSAGE,"Error!","No puede anular una orden de compra que no haya sido guardada");
        }
    }//GEN-LAST:event_btnAnularActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnAgregar;
    private javax.swing.JButton btnAnular;
    private javax.swing.JButton btnCancelar;
    private javax.swing.JButton btnEmitir;
    private javax.swing.JButton btnGuardar;
    private javax.swing.JButton btnQuitar;
    private javax.swing.JButton btnRegistrarRecepcion;
    private javax.swing.JButton btnSeleccionarProveedor;
    private javax.swing.JComboBox cmbFormaDeEntrega;
    private javax.swing.JComboBox cmbFormaDePago;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTable tblDetalle;
    private javax.swing.JTextField txtEstado;
    private com.toedter.calendar.JDateChooser txtFecha;
    private javax.swing.JTextField txtNroOrdenDeCompra;
    private javax.swing.JTextField txtProveedor;
    private javax.swing.JTextField txtTotal;
    // End of variables declaration//GEN-END:variables

    @Override
    public void actualizar(int id, String flag, Class tipo) {
        if(CALLBACK_SELECCION_PROVEEDOR.equals(flag))
        {
            if(tipo == Proveedor.class)
            {
                try
                {
                    HibernateUtil.beginTransaction();
                    Proveedor p = (Proveedor)HibernateUtil.getSession().load(tipo, id);
                    HibernateUtil.commitTransaction();
                    
                    if(p!=null)
                    {
                        // Aviso que si cambio el proveedor borro todo el detalle, pero solo si cambie el proveedor
                        if(this.proveedorSeleccionado!=null && this.proveedorSeleccionado.getId()!=p.getId() && tblDetalle.getRowCount()>0)
                        {
                            int seleccion = JOptionPane.showOptionDialog(
                                            this, // Componente padre
                                            "Si cambia el Proveedor para esta orden de compra, el detalle se vaciará ya que los items no son consistentes\n¿Desea continuar con el cambio?",
                                            "Seleccione una opción", // Titulo
                                            JOptionPane.YES_NO_CANCEL_OPTION,
                                            JOptionPane.QUESTION_MESSAGE,
                                            null,    // null para icono por defecto.
                                            new Object[] { "Si", "No"},    // null para YES, NO y CANCEL
                                            "Si");
                                            if (seleccion != -1)
                                            {
                                                if((seleccion + 1)==1)
                                                {
                                                    vaciarListaDetalle();
                                                }
                                                else
                                                {
                                                    return;
                                                }
                                            }
                        }
                        this.proveedorSeleccionado = p;
                        txtProveedor.setText(p.getRazonSocial());
                    }

                }catch(Exception e)
                {
                    HibernateUtil.rollbackTransaction();
                    mostrarMensaje(JOptionPane.ERROR_MESSAGE,"Error!","Se produjo un error al cargar el Proveedor Seleccionado\n"+e.getMessage());
                    e.printStackTrace();
                    return;
                } 
            }
        }
    }
    
    @Override
    public void actualizarConObjeto(String flag, Class tipo, Object[] data) {
        if(CALLBACK_SELECCION_ITEMDETALLE.equals(flag))
        {
            if(data[0] instanceof DetalleOrdenDeCompra)
            {
                DetalleOrdenDeCompra doc = (DetalleOrdenDeCompra) data[0];
                agregarDetalleOrdenCompraATabla(doc);
            }
        }        
    }    
    
    /**
     * Muestra un mensaje
     * @param tipo
     * @param titulo
     * @param mensaje 
     */
    public void mostrarMensaje(int tipo,String titulo,String mensaje)
    {
         JOptionPane.showMessageDialog(this.getParent(),mensaje,titulo,tipo);
    }

    private void initComboFormaDePago() {
        
        cmbFormaDePago.removeAllItems();
        try
            {
                HibernateUtil.beginTransaction();
                List<FormaDePago> listado = HibernateUtil.getSession().createQuery("from FormaDePago").list();
                HibernateUtil.commitTransaction();
                
                for (int i = 0; i < listado.size(); i++) {
                    FormaDePago fdp = listado.get(i);
                    Tupla tp = new Tupla(fdp.getId(),fdp.getNombre());
                    cmbFormaDePago.addItem(tp);
                }

            }catch(Exception e)
            {
                HibernateUtil.rollbackTransaction();
                mostrarMensaje(JOptionPane.ERROR_MESSAGE,"Error!","Se produjo un error al cargar las formas de Pago\n"+e.getMessage());
                e.printStackTrace();
                return;
            } 

    }

    private void initComboFormaDeEntrega() {
        for (int i = 0; i < OrdenDeCompra.FORMAS_DE_ENTREGA.length; i++) {
            String fde = OrdenDeCompra.FORMAS_DE_ENTREGA[i];
            Tupla tp = new Tupla(i,fde);
            cmbFormaDeEntrega.addItem(tp);
        }
    }

    /**
     * Setea el estado de la orden en el txt 
     */
    private void initEstado() {
        if(this.ordenDeCompraCargada!=null)
        {
            txtEstado.setText(this.ordenDeCompraCargada.getEstado());
            
            if(OrdenDeCompra.ESTADO_ANULADA.equals(this.ordenDeCompraCargada.getEstado()))
            {
                txtEstado.setBackground(OrdenDeCompra.COLOR_ESTADO_ANULADA);
                cambiarComportamientoEdicionDeVentana(false);
                btnAnular.setEnabled(false);
                btnRegistrarRecepcion.setEnabled(false);
            }
            if(OrdenDeCompra.ESTADO_EMITIDA.equals(this.ordenDeCompraCargada.getEstado()))
            {
                txtEstado.setBackground(OrdenDeCompra.COLOR_ESTADO_EMITIDA);
                cambiarComportamientoEdicionDeVentana(false);
                btnAnular.setEnabled(false);
                btnRegistrarRecepcion.setEnabled(true);
                btnEmitir.setEnabled(false);
            }
            if(OrdenDeCompra.ESTADO_PENDIENTE.equals(this.ordenDeCompraCargada.getEstado()))
            {
                txtEstado.setBackground(OrdenDeCompra.COLOR_ESTADO_PENDIENTE);
                btnAnular.setEnabled(true);
            }               
        }
    }
    
    private void cambiarComportamientoEdicionDeVentana(boolean enabled)
    {
        txtFecha.setEnabled(enabled);
        cmbFormaDeEntrega.setEnabled(enabled);
        cmbFormaDePago.setEnabled(enabled);
        btnSeleccionarProveedor.setEnabled(enabled);
        btnAgregar.setEnabled(enabled);
        btnQuitar.setEnabled(enabled);
        btnGuardar.setEnabled(enabled);
        btnAnular.setEnabled(enabled);
        tblDetalle.setEnabled(enabled);
    }

    private void initDatos(int idOrdenDeCompra) {
        // Cargo la Orden y muestro los datos
        try
        {
            HibernateUtil.beginTransaction();
            this.ordenDeCompraCargada = (OrdenDeCompra)HibernateUtil.getSession().load(OrdenDeCompra.class,idOrdenDeCompra);
            HibernateUtil.commitTransaction();
            
            if(this.ordenDeCompraCargada!=null)
            {
                // Numero
                txtNroOrdenDeCompra.setText(""+this.ordenDeCompraCargada.getId());
                // Proveedor
                if(this.ordenDeCompraCargada.getProveedor()!=null)
                {
                    this.proveedorSeleccionado = this.ordenDeCompraCargada.getProveedor();
                    txtProveedor.setText(this.proveedorSeleccionado.getRazonSocial());
                }
                // Fecha
                this.txtFecha.setDate( this.ordenDeCompraCargada.getFechaDeGeneracion());
                // Forma De Pago
                Tupla.seleccionarTuplaPorId(cmbFormaDePago, this.ordenDeCompraCargada.getFormaDePago().getId());
                // Forma De Entrega
                for (int i = 0; i < OrdenDeCompra.FORMAS_DE_ENTREGA.length; i++) {
                    String sfde = OrdenDeCompra.FORMAS_DE_ENTREGA[i];
                    if(sfde.equals(this.ordenDeCompraCargada.getFormaDeEntrega()))
                    {
                        Tupla.seleccionarTuplaPorId(cmbFormaDeEntrega, i);
                    }
                }
                // Estado
                txtEstado.setText(this.ordenDeCompraCargada.getEstado());  
                               
                // Detalles
                for (int i = 0; i < this.ordenDeCompraCargada.getDetalle().size(); i++) 
                {
                    DetalleOrdenDeCompra doc = this.ordenDeCompraCargada.getDetalle().get(i);
                    agregarDetalleOrdenCompraATabla(doc);
                }
            }

        }catch(Exception e)
        {
            HibernateUtil.rollbackTransaction();
            mostrarMensaje(JOptionPane.ERROR_MESSAGE,"Error!","Se produjo un error al cargar la Orden De Compra\n"+e.getMessage());
            e.printStackTrace();
            return;
        } 
    }
    
    private void agregarDetalleOrdenCompraATabla(DetalleOrdenDeCompra doc)
    {
        this.listadoDetalleOrdenDeCompra.add(doc);
        
        DefaultTableModel modelo = (DefaultTableModel)tblDetalle.getModel();
        
        Object[] fila = new Object[4];
            // Nombre de ItemComprable + Descripcion
            String nombre = "";
            if(doc.getDescripcion().isEmpty())
            {
                nombre = "<HTML><b>"+doc.getItem().getNombre() + "</b>";
            }
            else
            {
                nombre = "<HTML><b>"+doc.getItem().getNombre() + "</b> <i>("+doc.getDescripcion()+")</i>";
            }
            fila[0] = new Tupla(doc.hashCode(), nombre);
            
            fila[1] = doc.getCantidad();
            fila[2] = "$"+doc.getPrecioUnitario();
            fila[3] = "$"+doc.calcularSubTotal();
        modelo.addRow(fila);
        
        actualizarTotalCompra();
    }
    
    private void actualizarTotalCompra()
    {
        double total = 0 ;
        DefaultTableModel modelo = (DefaultTableModel)tblDetalle.getModel();
        for (int i = 0; i <  modelo.getRowCount(); i++) {
            String subtotal =  (String) modelo.getValueAt(i,3);
            subtotal = subtotal.replaceAll("\\$","");
            try
            {
                total += Double.parseDouble(subtotal);
            }catch(Exception e)
            {
                System.err.println("Error al calcular el total de la Orden de Compra");
            }
        }
        txtTotal.setText("$"+total);
    }

    /**
     * Crea una Nueva Orden de Compra (No usar para Actualizar)
     */
    private boolean crearYguardar() {
        
        OrdenDeCompra odc = new OrdenDeCompra();
        odc.setEstado(OrdenDeCompra.ESTADO_PENDIENTE);
        odc.setFechaDeGeneracion(txtFecha.getDate());
        odc.setFechaUltimaModificacion(new Date());
        odc.setFormaDeEntrega(OrdenDeCompra.FORMAS_DE_ENTREGA[cmbFormaDeEntrega.getSelectedIndex()]);
        odc.setProveedor(proveedorSeleccionado);
        
            // Forma de Pago
            try
            {
                Tupla tp = (Tupla) cmbFormaDePago.getSelectedItem();
                HibernateUtil.beginTransaction();
                FormaDePago fdp = (FormaDePago)HibernateUtil.getSession().load(FormaDePago.class,tp.getId());
                HibernateUtil.commitTransaction();
                odc.setFormaDePago(fdp);
            }catch(Exception e)
            {
                HibernateUtil.rollbackTransaction();
                mostrarMensaje(JOptionPane.ERROR_MESSAGE,"Error!","Se produjo un error al cargar la Forma de Pago\n"+e.getMessage());
                e.printStackTrace();
                return false;
            } 
            
            // Detalle de Orden de Compra
            for (int i = 0; i < listadoDetalleOrdenDeCompra.size(); i++) {
                DetalleOrdenDeCompra doc = listadoDetalleOrdenDeCompra.get(i);       
                odc.addDetalleOrdenDeCompra(doc);
            }    

            if(guardar(odc))
            {
                txtNroOrdenDeCompra.setText(""+odc.getId());
                this.ordenDeCompraCargada = odc;
                mostrarMensaje(JOptionPane.INFORMATION_MESSAGE,"Exito!","<HTML>La Orden de Compra se Creo exitosamente<br>y se le asigno el número: <b>"+odc.getId()+"</b>");
                return true;
            }
            else
            {
                return false;
            }
    }
    
    /**
     * Metodo que persiste la Orden De Compra en la DB
     * @param odc
     * @return 
     */
    private boolean guardar(OrdenDeCompra odc)
    {
      System.out.println("--------[Comenzando el saveOrUpdate de OrdenDeCompra]-------");
      try
        {   
            HibernateUtil.beginTransaction();
            
            HibernateUtil.getSession().saveOrUpdate(odc);
            
            for (int i = 0; i < odc.getDetalle().size(); i++) {
                DetalleOrdenDeCompra doc = odc.getDetalle().get(i);
                HibernateUtil.getSession().saveOrUpdate(doc.getItem());
                HibernateUtil.getSession().saveOrUpdate(doc);
            }
            
            HibernateUtil.getSession().saveOrUpdate(odc);
            
            HibernateUtil.commitTransaction();
            
        }catch(Exception e)
        {
            HibernateUtil.rollbackTransaction();
            e.printStackTrace();
            mostrarMensaje(JOptionPane.ERROR_MESSAGE,"Error!","Se produjo un error al Generar y Guardar la Orden De Compra\n"+e.getMessage());
            return false;
        }       
        return true;
    }

    private void emitirOrdenDeCompra() {
        
        EmitirOrdenDeCompra informe = new EmitirOrdenDeCompra(ordenDeCompraCargada);
        informe.setNombreReporte("Orden de Compra : "+ordenDeCompraCargada.getId());
        informe.setNombreArchivo("Compras-"+ordenDeCompraCargada.getId(),ReportDesigner.REPORTE_TIPO_COMPRAS);

        try 
        {
            informe.makeAndShow(new HashMap<String,Object>());
        } catch (DocumentException ex) {
            mostrarMensaje(JOptionPane.ERROR_MESSAGE,"Error!","No se pudo crear el informe\nVerifique los datos e intentelo nuevamente");
        } catch (FileNotFoundException ex) {
            mostrarMensaje(JOptionPane.ERROR_MESSAGE,"Error!","No se pudo crear el archivo donde guardar el informe");
        }    
    }

    /**
     * Actualiza el objeto antes de pedir que se guarde
     */
    private boolean actualizarYGuardar() {
        OrdenDeCompra odc = this.ordenDeCompraCargada;
        odc.setFechaDeGeneracion(new Date());
        odc.setFechaUltimaModificacion(new Date());
        odc.setFormaDeEntrega(OrdenDeCompra.FORMAS_DE_ENTREGA[cmbFormaDeEntrega.getSelectedIndex()]);
        odc.setProveedor(proveedorSeleccionado);
        
            // Forma de Pago
            try
            {
                Tupla tp = (Tupla) cmbFormaDePago.getSelectedItem();
                HibernateUtil.beginTransaction();
                FormaDePago fdp = (FormaDePago)HibernateUtil.getSession().load(FormaDePago.class,tp.getId());
                HibernateUtil.commitTransaction();
                odc.setFormaDePago(fdp);
            }catch(Exception e)
            {
                HibernateUtil.rollbackTransaction();
                mostrarMensaje(JOptionPane.ERROR_MESSAGE,"Error!","Se produjo un error al cargar la Forma de Pago\n"+e.getMessage());
                e.printStackTrace();
                return false;
            } 
            
            // Detalle de Orden de Compra
            for (int i = 0; i < listadoDetalleOrdenDeCompra.size(); i++) {
                DetalleOrdenDeCompra doc = listadoDetalleOrdenDeCompra.get(i);
                // Solo lo agrego si es nuevo
                if(doc.getId()==0)
                {
                    // Lo agrego
                    odc.addDetalleOrdenDeCompra(doc);
                }
                else
                {
                    //TODO: Tengo que actualizar los datos ?? ( Solo si hay modificar )
                }
            }    

            if(guardar(odc))
            {
                txtNroOrdenDeCompra.setText(""+odc.getId());
                mostrarMensaje(JOptionPane.INFORMATION_MESSAGE,"Exito!","<HTML>La Orden de Compra número <b>"+odc.getId()+"</b> se actualizó exitosamente");
                return true;
            }
            {
                return false;
            }        
    }

    /**
     * Valido que todos los datos sean correctos antes de guardar
     * @return 
     */
    private boolean validar() {
        
        boolean validado = true;
        StringBuilder msg = new StringBuilder("<HTML>Para continuar, asegurese que:");
        
        // Fecha de la Orden de Compra
        if(txtFecha.getDate()==null)
        {
            msg.append("<br>- La <b>Fecha</b> de la orden de compra no está vacía");
            validado = false;
        }
        // Proveedor
        if(txtProveedor.getText().isEmpty() || this.proveedorSeleccionado==null)
        {
            msg.append("<br>- Elija el <b>Proveedor</b> al que se le realizarán las compras");
            validado = false;
        }
        // Al menor un item en la compra
        if(tblDetalle.getRowCount()<=0)
        {
            msg.append("<br>- Agregue al menos un <b>Item</b> al detalle de la compra");
            validado = false;
        }

        if(!validado)
        {
            mostrarMensaje(JOptionPane.ERROR_MESSAGE,"Error de Validación!",msg.toString());
        }
        
        return validado;
    }

    /**
     * Cambia el estado de la ODC a Emitida 
     * ATENCION! Solo debe llamarse despues de guardar la ODC exitosamente
     */
    private boolean cambiarEstadoAEmitida() {
        // Si se guardo exitosamente
        if(this.ordenDeCompraCargada!=null && this.ordenDeCompraCargada.getId()!=0)
        {
            // Si ya esta emitida, no hago nada
            if(OrdenDeCompra.ESTADO_EMITIDA.equals(this.ordenDeCompraCargada.getEstado()))
            {
                return true;
            }
            
            // Sino cambio el estado !!
            this.ordenDeCompraCargada.setEstado(OrdenDeCompra.ESTADO_EMITIDA);
            try
            {
                HibernateUtil.beginTransaction();

                HibernateUtil.getSession().saveOrUpdate(this.ordenDeCompraCargada);

                HibernateUtil.commitTransaction();
            }catch(Exception e)
            {
                HibernateUtil.rollbackTransaction();
                mostrarMensaje(JOptionPane.ERROR_MESSAGE,"Error!","Se produjo un error al Emitir y Cerrar la orden de Compra\n"+e.getMessage());
                e.printStackTrace();
                return false;
            }  
        }
        mostrarMensaje(JOptionPane.INFORMATION_MESSAGE,"Exito!","Se Guardó y Emitió exitosamente la Orden de Compra !");
        btnAnular.setEnabled(true);
        initEstado();
        return true;
    }

    /**
     * Setea el ancho de las columnas de la tabla por defecto
     */
    private void initAnchoColumnasTablaDetalles() {
        int anchoColumna = 0; 
        TableColumnModel modeloColumna = tblDetalle.getColumnModel(); 
        TableColumn columnaTabla; 
        for (int i = 0; i < tblDetalle.getColumnCount(); i++) { 
            columnaTabla = modeloColumna.getColumn(i); 
            switch(i){ 
                case 0: anchoColumna = 500; 
                        break; 
                case 1: anchoColumna = 100; 
                        break; 
                case 2: anchoColumna = 100; 
                        break; 
                case 3: anchoColumna = 100; 
                        break; 
            }                      
            columnaTabla.setPreferredWidth(anchoColumna); 
            columnaTabla.setWidth(anchoColumna);
        } 
    }

    /**
     * Este metodo llena la ventana, cuando esta ventana, se llama con los datos
     * para rellenar (se genera una orden de compra, digamos desde una obra)
     * Asi que tiene la obra para asociar  y el detalle !!
     * @param obra
     * @param p
     * @param listaItemsOrden 
     */
    private void initDatos(PedidoObra obra, Proveedor p, List<DetalleOrdenDeCompra> listaItemsOrden) {
        
        //TODO: Por ahora no hago nada con la obra hasta tener ejecucion lista
        // Proveedor
        if(p!=null)
        {
            txtProveedor.setText(p.toString());
            this.proveedorSeleccionado = p;
        }
        // Fecha .. la actual
        txtFecha.setDate(new Date());
        // Detalle
        for (int i = 0; i < listaItemsOrden.size(); i++) {
            DetalleOrdenDeCompra item = listaItemsOrden.get(i);
            agregarDetalleOrdenCompraATabla(item);
        }
        
    }

    /**
     * Vacia el detalle de la orden de compra
     */
    private void vaciarListaDetalle() {
        TablaUtil.vaciarDefaultTableModel((DefaultTableModel)tblDetalle.getModel());
    }

    private void mostrarRecepcion(int id) {
        RegistrarRecepcionDeRecursos rrr = new RegistrarRecepcionDeRecursos(id);
        SwingPanel.getInstance().addWindow(rrr);
        rrr.setVisible(true);
    }

    /**
     * Anula una orden de Compra!!
     * @param id 
     */
    private void anularOrdenDeCompra(int id) {
        
        // Para evitar problemas, cargo la orden y la anulo desde DB
        try
        {
            HibernateUtil.beginTransaction();
            OrdenDeCompra odc = (OrdenDeCompra) HibernateUtil.getSession().load(OrdenDeCompra.class, id);
            
            // Cambio el estado
            odc.setEstado(OrdenDeCompra.ESTADO_ANULADA);
            HibernateUtil.getSession().saveOrUpdate(odc);
            
            HibernateUtil.commitTransaction();

        }catch(Exception e)
        {
            HibernateUtil.rollbackTransaction();
            mostrarMensaje(JOptionPane.ERROR_MESSAGE,"Error!","Se produjo un error al cargar la Orden De Compra\n"+e.getMessage());
            e.printStackTrace();
            return;
        } 
        // Exito !
        mostrarMensaje(JOptionPane.INFORMATION_MESSAGE,"Exito!","<HTML>La orden de compra <b>'"+id+"'</b> se anulo exitosamente!");
        initEstado();
    }


}
